#!/usr/bin/env python

# --------------------------------------
# projects/python/collatz/TestCollatz.py
# Copyright (C) 2009
# Glenn P. Downing
# --------------------------------------

# To run the tests
#     TestPrimes.py

# To document the tests
#     pydoc -w TestPrimes 

import main
import unittest

# ----------
# TestReader
# ----------

class TestReader (object) :
    def __init__ (self, s) :
        self.s = s

    def read (self) :
        return self.s

# ----------
# TestWriter
# ----------

class TestWriter (object) :
    def str (self) :
        return self.s

    def write (self, *a) :
        self.s = str(a[0])
        for w in a[1:] :
            self.s += ' '
            self.s += str(w)
        self.s += '\n'

# -----------
# TestCollatz
# -----------

class TestPrimes (unittest.TestCase) :
    # ----
    # read
    # ----

    def test_read (self) :
        reader = TestReader('25\n')
        main.my_read(reader)
        self.assert_(main.i ==  25)

    # ----
    # eval
    # ----
    
    def test_isPrime1 (self) :
	"""
		Tests we got from a list of prime numbers.
	"""
        self.assert_(main.is_prime(102059))
        self.assert_(main.is_prime(82813))
        self.assert_(main.is_prime(69191))
        self.assert_(main.is_prime(64553))
        self.assert_(main.is_prime(58321))
        self.assert_(main.is_prime(46889))
        self.assert_(main.is_prime(32309))
        self.assert_(main.is_prime(6883))
        self.assert_(main.is_prime(19079))
        self.assert_(main.is_prime(18301))
    
    def test_isPrime2 (self) :
	"""
		Numbers that aren't prime. What jerks.
	"""
        self.assert_(not main.is_prime(8))
        self.assert_(not main.is_prime(9))
        self.assert_(not main.is_prime(1))
        self.assert_(not main.is_prime(0))
        self.assert_(not main.is_prime(41041))
        self.assert_(not main.is_prime(101101))
        
    def test_Format (self) :
	"""
		Make sure we're printing output in the format we expect.
	"""
        main.i = 8
        main.my_eval()
        self.assert_(main.out == "2 2 2 2")
        
    def test_Sum (self) :
        """
		Make sure that the primes we generate for some sample numbers do in fact add up to the sample number.
	"""
        testNums = [8, 9, 100, 1000, 10000, 1000000, 10000000, 293847]
        
        for testNum in testNums :
            main.i = testNum
            mainSum = testNum
            
            main.my_eval()
            nums = map(int, main.out.split())
            for num in nums :
		self.assert_(main.is_prime(num))
                mainSum -= num
            self.assert_(mainSum == 0)
    
    def test_Impossible (self) :
	"""
		Make sure numbers that have no solution get handled correctly
	"""
        testNums = range(-1, 8)
        for testNum in testNums :
            main.i = testNum
            main.my_eval()
            self.assert_(main.out == "Impossible.")
    # -----
    # print
    # -----

    def test_print (self) :
        main.out = "2 2 2 2"
        writer = TestWriter()
        main.my_print(writer)
        self.assert_(writer.str() == "2 2 2 2\n")

if __name__ == "__main__" :
    unittest.main()
